package com.xbongbong.process.task;

import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasProcessTaskEntity;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateNodeEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.model.PaasProcessTaskModel;
import com.xbongbong.paas.pojo.dto.ProcessConditionValidDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskAddDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.SysUserHelp;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author: wufeng
 * @date: 2018/11/30 19:30
 * @desrcption: 流程开始时，获取任务
 */
@Component
public class NodeTaskListStartProcessServiceImpl implements NodeTaskListService<ProcessConditionValidDTO> {

    private static final Logger LOG = LoggerFactory.getLogger(NodeTaskListStartProcessServiceImpl.class);

    @Resource
    private UserModel userModel;
    @Resource
    private PaasProcessTaskModel paasProcessTaskModel;
    @Resource
    private SysUserHelp sysUserHelp;

    /**
     *
     * @param optionalRangeList 可选范围列表
     * @param processConditionValidDTO
     * @param paasProcessTemplateNodeEntityExt 目标节点/ 下一流程的节点
     * @return
     * @throws XbbException
     */
    @Override
    public List<ProcessNodeTaskAddDTO> getNodeTaskList(List<OptionalRangeEntity> optionalRangeList, ProcessConditionValidDTO processConditionValidDTO,
                                                       PaasProcessTemplateNodeEntityExt paasProcessTemplateNodeEntityExt, Integer taskType) throws XbbException {
        // 生成负责人任务
        List<ProcessNodeTaskAddDTO> resultUserNodeTaskList = new ArrayList<>();
        List<ProcessNodeTaskAddDTO> userNodeTaskList = new ArrayList<>();
        try {

            String corpid = processConditionValidDTO.getCorpid();
            String creatorId = processConditionValidDTO.getUserId();
            if (processConditionValidDTO.getTaskId() != null) {
                PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(processConditionValidDTO.getTaskId().intValue(), corpid);
                creatorId = paasProcessTaskEntity.getCreatorId();
            }

            Set<String> userList = sysUserHelp.getUserListByOptionalRange(corpid, optionalRangeList, processConditionValidDTO.getData(), creatorId);

            if (!userList.isEmpty()) {
                getOptionalRange(userNodeTaskList, processConditionValidDTO, userList, paasProcessTemplateNodeEntityExt, taskType, OptionalRangeEnum.MANAGER);
            }
            // 去重
            if (!userNodeTaskList.isEmpty()) {
                Map<String, ProcessNodeTaskAddDTO> userMap = new HashMap<>(userNodeTaskList.size());
                userNodeTaskList.forEach((item) -> {
                    userMap.put(item.getUserId(), item);
                });
                Iterator iterator = userMap.keySet().iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next().toString();
                    ProcessNodeTaskAddDTO userVO = userMap.get(key);
                    resultUserNodeTaskList.add(userVO);
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessCondition获取流程中负责人或者抄送人出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return resultUserNodeTaskList;
    }

    /**
     * 根据角色/用户/部门id获取用户可选范围
     *
     * @param userNodeTaskList                 用户列表
     * @param processConditionValidDTO
     * @param list
     * @param paasProcessTemplateNodeEntityExt 目标节点/ 下一流程的节点的属性
     * @param taskType
     * @param type                             角色，部门，主管
     * @throws XbbException
     */
    public void getOptionalRange(List<ProcessNodeTaskAddDTO> userNodeTaskList, ProcessConditionValidDTO processConditionValidDTO,
                                 Collection<String> list, PaasProcessTemplateNodeEntityExt paasProcessTemplateNodeEntityExt, Integer taskType, OptionalRangeEnum type) throws XbbException {
        try {
            Map<String, Object> params = BeanUtil.convertBean2Map(processConditionValidDTO, true);
            if (type == OptionalRangeEnum.ROLE) {
                params.put("roleIdIn", list);
            } else if (type == OptionalRangeEnum.DEPT) {
                params.put("depIdIn", list);
            } else {
                params.put("userIdIn", list);
            }
            // 排除离职员工
            params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());

            List<UserEntity> userList = userModel.findEntitys(params);
            if (userList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
            }
            userList.forEach((item) -> {
                ProcessNodeTaskAddDTO processNodeTaskAddDTO = new ProcessNodeTaskAddDTO();
                BeanUtil.copyProperties(processConditionValidDTO, processNodeTaskAddDTO);
                processNodeTaskAddDTO.setTemplateNodeId(paasProcessTemplateNodeEntityExt.getId());
                processNodeTaskAddDTO.setTaskType(taskType);
                processNodeTaskAddDTO.setTaskId(processConditionValidDTO.getTaskId());
                processNodeTaskAddDTO.setNodeType(paasProcessTemplateNodeEntityExt.getType());
                processNodeTaskAddDTO.setSignType(paasProcessTemplateNodeEntityExt.getSignType());
                processNodeTaskAddDTO.setUserId(item.getUserId());
                processNodeTaskAddDTO.setCreatorId(processConditionValidDTO.getUserId());
                userNodeTaskList.add(processNodeTaskAddDTO);
            });
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessCondition根据" + type.getMemo() + "id获取用户数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    private void setDynamicMap(Map<String, List<String>> dynamicMap, String key, String value) {
        if(dynamicMap.containsKey(key)) {
            dynamicMap.get(key).add(value);
        } else {
            List<String> values = new ArrayList<>();
            values.add(value);
            dynamicMap.put(key, values);
        }
    }


}
